package com.rookie.controller;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rookie.common.dto.PasswordDto;
import com.rookie.common.lang.Const;
import com.rookie.common.lang.Result;
import com.rookie.entity.Role;
import com.rookie.entity.User;
import com.rookie.entity.UserRole;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 前端控制器
 */
@RestController
@RequestMapping("/rookie/user")
public class UserController extends BaseController {

    /**
     * 查询用户头像信息
     */
    @GetMapping("userInfo")
    public Result userInfo(Principal principal) {
        User user = userService.getUserByUsername(principal.getName());
        Map<Object, Object> map = MapUtil.builder().put("id", user.getId())
                .put("username", user.getUsername())
                .put("avatar", user.getAvatar()).map();
        return Result.success(map);
    }

    /**
     * 添加
     */
    @PostMapping("save")
    @PreAuthorize("hasAuthority('sys:user:save')")
    public Result save(@Validated @RequestBody User user) {
        user.setCreateTime(LocalDateTime.now());
        user.setPassword(bCryptPasswordEncoder.encode(Const.DEAFULT_PASSWORD));
        user.setAvatar(Const.DEAFULT_AVATAR);
        userService.save(user);
        return Result.success("");
    }

    /**
     * 分页列表
     */
    @GetMapping("list")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public Result list(String username) {
        Page<User> userPage = userService.page(getPage(), new LambdaQueryWrapper<User>().like(StringUtils.isNotBlank(username), User::getUsername, username));
        userPage.setRecords(userPage.getRecords().stream().peek(user -> user.setRoleList(roleService.getRoleListByUId(user.getId()))).collect(Collectors.toList()));
        return Result.success(userPage);
    }

    /**
     * 根据id查询用户信息
     */
    @GetMapping("getInfoById/{id}")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public Result getInfoById(@PathVariable Long id) {
        User user = userService.getById(id);
        List<Role> roleList = roleService.getRoleListByUId(id);
        user.setRoleList(roleList);
        return Result.success(user);
    }

    /**
     * 修改
     */
    @PostMapping("update")
    @PreAuthorize("hasAuthority('sys:user:update')")
    public Result update(@Validated @RequestBody User user) {
        user.setUpdateTime(LocalDateTime.now());
        userService.updateById(user);
        return Result.success("");
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @Transactional(rollbackFor = Exception.class)
    public Result delete(@RequestBody Long[] ids) {
        userService.removeByIds(Arrays.asList(ids));
        // 删除中间表
        userRoleService.remove(new LambdaQueryWrapper<UserRole>().in(UserRole::getUserId, Arrays.asList(ids)));
        // 清除Redis缓存
        Arrays.stream(ids).forEach(id -> userService.clearRedisAuthorityByUser(id));
        return Result.success("");
    }

    /**
     * 分配角色
     */
    @PostMapping("assignRoles/{userId}")
    @PreAuthorize("hasAuthority('sys:user:role')")
    @Transactional(rollbackFor = Exception.class)
    public Result assignRoles(@PathVariable Long userId, @RequestBody Long[] roleIds) {
        userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId));
        ArrayList<UserRole> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(roleId -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleList.add(userRole);
        });
        userRoleService.saveBatch(userRoleList);
        // 清除Redis缓存
        userService.clearRedisAuthorityByUser(userId);
        return Result.success("");
    }

    /**
     * 重置密码
     */
    @PostMapping("resetPassword")
    @PreAuthorize("hasAuthority('sys:user:repass')")
    public Result resetPassword(@RequestBody Long userId) {
        User user = new User();
        user.setId(userId);
        user.setPassword(bCryptPasswordEncoder.encode(Const.DEAFULT_PASSWORD));
        user.setUpdateTime(LocalDateTime.now());
        userService.updateById(user);
        return Result.success("");
    }

    /**
     * 更新密码
     */
    @PostMapping("updatePassword")
    public Result updatePassword(@Validated @RequestBody PasswordDto passwordDto, Principal principal) {
        User user = userService.getUserByUsername(principal.getName());
        boolean matches = bCryptPasswordEncoder.matches(passwordDto.getOldPassword(), user.getPassword());
        if (!matches) return Result.fail("旧密码不正确");
        user.setPassword(bCryptPasswordEncoder.encode(passwordDto.getNewPassword()));
        user.setUpdateTime(LocalDateTime.now());
        userService.updateById(user);
        return Result.success("");
    }

}
